home *** CD-ROM | disk | FTP | other *** search
- /* Mann-Whitney U Test */
-
- options results
- if ~show('P','TCALC') then do
- address command 'run turbocalc:turbocalc'
- address command 'waitforport TCALC'
- loadflag=1
- end
- address 'TCALC'
- 'DEFPUBSCREEN()'
- /* Add-in Rexx Math Library needed for some routines */
- signal on syntax
- if ~show('l','rexxmathlib.library') then
- call addlib('rexxmathlib.library',0,-30)
- if ~show('l','rexxreqtools.library') then
- call addlib('rexxreqtools.library',0,-30)
- if ~show('l','rexxsupport.library') then
- call addlib('rexxsupport.library',0,-30)
- /* add to library list */
- signal off syntax
-
- /* Start Main Routine */
- if loadflag=1 then 'Load()'
- 'ActivateWindow()'
- range=rtgetstring(,"Enter Cell Range for Input","Input Request") /*,,'rt_pubscrname="TCALC"')*/
- colon=pos(":",range)
- if colon=0 then do
- 'Message "Please select a range before executing this script"'
- 'DEFPUBSCREEN("Workbench")'
- exit
- end
-
- /* Find cell references and cell, column numbers */
- start_cell=substr(range,1,colon-1)
- end_cell=substr(range,colon+1)
- start_row=cellrow(start_cell)
- end_row=cellrow(end_cell)
- start_col=cellcol(start_cell)
- end_col=cellcol(end_cell)
- NRows=end_row-start_row+1
- NCols=end_col-start_col+1
- if NCols>2 then do
- 'Message "Only two columns allowed!"'
- 'DEFPUBSCREEN("Workbench")'
- exit
- end
-
- /* Get cell reference for output range */
- out_cell=rtgetstring(,"Enter Cell Reference for Output","Input Request") /*,,'rt_pubscrname="TCALC"')*/
- if out_cell="" then do
- 'DEFPUBSCREEN("Workbench")'
- exit
- end
- if length(out_cell)<2 | datatype(left(out_cell,1),'n') then do
- 'Message "Invalid cell reference"'
- 'DEFPUBSCREEN("Workbench")'
- exit
- end
- /* Suppress Screen Redraw to Speed Things Up */
- 'Refresh 0'
-
- /* Open a small output window on tcalc screen*/
- fo=0
- CR='0a'x
- DisplayMsg="Calculating...Please Wait."||CR||"User input is disabled during calculation."||CR
- if open(6Info, 'con:100/0/450/80/Progress/SCREEN TCALC', w) then do
- call writeln(6Info, DisplayMsg)
- fo=1
- end
- else do
- 'Message "TCALC Screen not available for Progress messages"'
- end
- CALL DELAY(150)
-
- /* Get cell references for top cell in each column */
- 'SelectCell' start_cell
- do col=start_col to end_col
- 'GetCursorPos'
- top_cell.col=result
- 'Column 1'
- end
-
- /* Get labels for later use on output */
- 'SelectCell' start_cell
- 'GetValue'
- testlabel=result
- testlabel=strip(testlabel)
- if datatype(testlabel,'n')=1 then do
- labelflag=0
- do x=1 to NCols
- title.x="Column "||x
- end
- end
- else do
- labelflag=1
- NRows=NRows-1
- do x=1 to NCols
- 'GetValue'
- str=result
- title.x=translate(strip(str),"_"," ")
- 'Column 1'
- end
- end
- if fo then call writech(6Info,"Progress...10 ")
-
- /* Get data from cell range */
- col=start_col
- lav=0
- tot=0
- count.=0
- total.=0
- do x=1 to NCols
- 'SelectCell' top_cell.col
- if labelflag=1 then 'CursorDown 1'
- do y=1 to NRows
- 'GetValue'
- valtest=result
- if datatype(valtest)='NUM' then do
- 'GetValue'
- val=result
- data.x.y=val
- count.x=1+count.x
- end
- 'CursorDown 1'
- end
- col=col+1
- val=0
- end
- if fo then call writech(6Info,"20 ")
-
- /* Sort Values */
- call Sort()
- if fo then call writech(6Info,"30 ")
-
- /* Create One Total Data Array */
-
- z=0
- totdat.=0
- Do x=1 to NCols
- count=count.x
- Do y=1 to count
- z=z+1
- val=data.x.y
- totdat.z=val
- end
- end
- val=0
- avrank=0
- cnt=0
- N=z
- if fo then call writech(6Info,"40 ")
-
- /* Sort Total Array */
- call SortB()
- if fo then call writech(6Info,"50 ")
-
- /* Calculate Ranks */
-
- Rank.=0
- Do x=1 to NCols
- z=0
- Do y=1 to NRows
- z=0
- Do z=1 to N
- if data.x.y=totdat.z then Do
- cnt=1
- beginrank=z
- avrank=z
- endrank=0
- Do until endrank ~=0
- z=z+1
- if (data.x.y) ~= (totdat.z) then endrank=z-1
- avrank=avrank+z
- cnt=cnt+1
- end
- val=trunc((avrank/cnt)-.5,2)
- Rank.x.y=val
- Leave z
- end
- end
- end
- end
-
- val=0
- if fo then call writech(6Info,"60 ")
-
- /* Calculate Sums etc. of Ranks */
-
- sumr.=0
- sumrsq.=0
- totssr=0
- temp=0
- Do x=1 to NCols
- count=count.x
- Do y=1 to count
- sumr.x=(sumr.x)+(Rank.x.y)
- sumrsq.x=(sumrsq.x)+(Rank.x.y)**2
- end
- end
- totssr=(sumrsq.1)+sumrsq.2
- if fo then call writech(6Info,"70 ")
-
- /* Calculate U Statistic */
- N1=0
- N2=0
- US1=0
- US2=0
- If (count.1)<(count.2)|(count.1)=(count.2) then do
- N1=count.1
- N2=count.2
- US1=N1*N2+((N1*(N1+1))/2)-sumr.1
- US2=N1*N2+((N2*(N2+1))/2)-sumr.2
- end
- else do
- N1=count.2
- N2=count.1
- US1=N1*N2+((N1*(N1+1))/2)-sumr.2
- US2=N1*N2+((N2*(N2+1))/2)-sumr.1
- end
- meanu=(N1*N2)/2
- varu=(N1*N2*(N1+N2+1))/12
- StDev=sqrt(varu)
- Select
- when (count.1>7)&(count.2>7) then zip=1
- when (count.1>=20)|(count.2>=20) then zip=1
- otherwise
- zip=0
- end
- if fo then call writech(6Info,"80 ")
-
- /* Calculate z and Probability of z */
- if US1<=US2 then U=US1
- else U=US2
- zed1=(U-meanu)/SQRT(varu)
- sn=sign(zed1)
- /*select
- when zed1<(-6.5) then P=0
- when zed1>6.5 then P=1
- otherwise
- P=calcp(zed1)
- end
- if sn~=-1 then P=1-P
- */
- call NPROB(zed1)
- PTM=ABS(P-0.5)
- if fo then call writech(6Info,"90 ")
-
- /* Calculate T statistic */
- /*NT=N1+N2
- TTOP=(sumr.1)-(N1*((NT+1)/2))
- TBOT1=((N1*N2)/(NT*(NT-1)))*totssr
- TBOT2=(N1*N2*(NT+1)**2)/(4*(NT-1))
- TBOT=sqrt(TBOT1-TBOT2)
- MannT=TTOP/TBOT
- sn=sign(MannT)*/
-
- /* Calculate U Probability */
- /*PU=calcp(MannT)
- if sn~=-1 then PU=1-PU*/
- if fo then do
- call writeln(6Info,"100")
- call writeln(6Info,"Writing output to window...")
- end
-
-
- /* Output */
- 'SelectCell' out_cell
- 'ColumnWidth 20'
- 'Put "Mann-Whitney U Test"'
- 'CursorDown 1'
- 'Put "Sorted Data"'
- 'CursorDown 1'
- Do x=1 to NCols
- title=title.x
- 'Alignment 2'
- 'Put' title
- 'CursorDown 1'
- count=count.x
- Do y=1 to count
- 'Put' data.x.y
- 'CursorDown 1'
- end
- 'CursorUp' count+1
- 'Column 1'
- end
- 'SelectCell' out_cell
- 'CursorDown' NRows+4
- 'GetCursorPos'
- newpos=result
- 'Put "Table of Ranks for Sorted Data"'
- 'CursorDown 1'
- Do x=1 to NCols
- count=count.x
- Do y=1 to count
- 'Put' Rank.x.y
- 'CursorDown 1'
- end
- 'CursorUp' count
- 'Column 1'
- end
- 'SelectCell' newpos
- 'CursorDown' NRows+3
- 'GetCursorPos'
- cpos=result
- 'Put "U (Sample 1):"'
- 'CursorDown 1'
- 'Put "U (Sample 2):"'
- 'CursorDown 1'
- 'Put "No. of Cases:"'
- 'CursorDown 1'
- 'Put "N (Sample 1):"'
- 'CursorDown 1'
- 'Put "N (Sample 2):"'
- 'CursorDown 1'
- 'Put "Normal Approximation:"'
- 'CursorDown 1'
- 'Put "Mean:"'
- 'CursorDown 1'
- 'Put "Variance:"'
- 'CursorDown 1'
- 'Put "St.Dev:"'
- 'CursorDown 1'
- 'Put "z:"'
- 'CursorDown 1'
- /*'Put "Prob.(Z<=z):"'*/
- 'Put "Prob (z to Left tail):"'
- 'CursorDown 1'
- 'Put "Prob (z to mean):"'
- 'CursorDown 1'
- 'Put "Prob (z to Right tail):"'
- 'CursorDown 1'
- 'Put "Density Function:"'
- /*'CursorDown 1'
- 'Put "z (tie adjusted):"'
- 'CursorDown 1'
- 'Put "Prob.(Z<=z):"'*/
- 'SelectCell' cpos
- 'Column 1'
- 'Put' US1
- 'CursorDown 1'
- 'Put' US2
- 'CursorDown 1'
- 'Put' N
- 'CursorDown 1'
- 'Put' count.1
- 'CursorDown 1'
- 'Put' count.2
- 'CursorDown 2'
- 'Put' format(meanu,,4)
- 'CursorDown 1'
- 'Put' format(varu,,4)
- 'CursorDown 1'
- 'Put' format(StDev,,4)
- 'CursorDown 1'
- 'Put' format(zed1,,4)
- 'CursorDown 1'
- /*'Put' format(P,,6)*/
- 'Put' format(P,,6)
- 'CursorDown 1'
- 'Put' format(PTM,,6)
- 'CursorDown 1'
- 'Put' format(Q,,6)
- 'CursorDown 1'
- 'Put' format(PDF,,4)
- 'Column -1'
- 'CursorDown 1'
- 'Put "Z Critical One-tail(95%):"'
- 'Column 1'
- 'Put' 1.65
- 'CursorDown 1'
- 'Put' 2.33
- 'Column -1'
- 'Put "Z Critical One-tail(99%):"'
- 'CursorDown 1'
- 'Put "Z Critical Two-tail(95%):"'
- 'Column 1'
- 'Put' 1.96
- 'CursorDown 1'
- 'Put' 2.58
- 'Column -1'
- 'Put "Z Critical Two-tail(99%):"'
- /*'CursorDown 1'
- 'Put' format(MannT,,4)
- 'CursorDown 1'
- 'Put' format(PU,,6)*/
- 'Refresh 1'
- 'Refresh 2'
- /*'Message' "Finished"*/
- /*indicate the main script is finished*/
- DisplayMsg="Cleaning up ...."||CR||"Exiting"
- result=writeln(6Info, DisplayMsg)
- if result~=0 then do
- /*Wait 3 seconds*/
- CALL DELAY(150)
- /* close window*/
- result=close(6Info)
- end
- 'DEFPUBSCREEN("Workbench")'
- exit
-
- /* Procedures */
-
- cellrow: procedure
- do
- parse arg cell
- do charpos=2 to length(cell)
- if datatype(substr(cell,charpos,1),n) then return substr(cell,charpos)
- end
- return 0
- end
- Return
-
- cellcol: procedure
- do
- parse arg cell
- labels="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- cell=upper(cell)
- len=length(cell)
- val=0
- do charpos=1 to len
- if datatype(substr(cell,charpos,1),n) then
- do cell=reverse(substr(cell,1,charpos-1))
- do x=1 to length(cell)
- val=(26**(x-1))*pos(substr(cell,x,1),labels)+val
- end
- return val
- end
- end
- return 0
- end
- Return
-
- /* It is important to put the exposed array at the end of the next line */
- Sort: procedure expose NCols count. data.
- do x=1 to NCols
- NRows=count.x
- L=(xtoy(2,int(log(NRows)/log(2))))-1
- Do Until L<1
- L=trunc(int(L/2))
- Do J=1 to L
- Do K=J+L To NRows By L
- I=K
- dumdat=data.x.I
- Do while I>L
- y=I-L
- If data.x.y ~> dumdat then Leave
- data.x.I=data.x.y
- I=I-L
- End
- data.x.I=dumdat
- End
- End
- End
- End
- Return
-
- /* It is important to put the exposed array at the end of the next line */
- SortB: procedure expose N totdat.
- L=(xtoy(2,int(log(N)/log(2))))-1
- Do Until L<1
- L=trunc(int(L/2))
- Do J=1 to L
- Do K=J+L To N By L
- I=K
- dumdat=totdat.I
- Do while I>L
- z=I-L
- If totdat.z ~> dumdat then Leave
- totdat.I=totdat.z
- I=I-L
- End
- totdat.I=dumdat
- End
- End
- End
- Return
-
- syntax:
- if arg(1)='FAIL' then do
- 'Message "Library is unavailable."'
- 'DEFPUBSCREEN("Workbench")'
- exit
- end
- 'DEFPUBSCREEN("Workbench")'
- exit
-
- Format: procedure
-
- arg number, before, after
- CallLine = SIGL
- if ~datatype(CallLine, 'N') then CallLine = '??'
-
- /* Make sure we have a number as first (required) argument */
- if ~datatype(number, 'N') then do
- if number = '' then
- fc = 17 /* Wrong number of arguments */
- else
- fc = 47 /* Arithmetic conversion error */
- signal FormatSyntaxError
- end
- num = number + 0
- if before = '' & after = '' then
- return num
- else do
- parse var num integer '.' fraction
- if before = '' then before = length(integer)
- if after = '' then after = length(fraction)
- if ~datatype(before, N) | ~datatype(after, N) then
- do fc = 18
- signal FormatSyntaxError
- end
- if before < length(integer) then do
- fc = 18
- signal FormatSyntaxError
- end
- if after ~= length(fraction) then do
- fraction = trunc(('.'fraction'0') + ('.'copies('0', after)'5'), after)
- if integer<1&integer>-1 then integer=integer
- else integer = integer + (fraction % 1)
- fraction = substr(fraction, 3)
- end
- if fraction >= 0 then
- return right(integer, before)'.'fraction
- else
- return right(integer, before)
- end
-
- FormatSyntaxError:
- if show('F', STDERR) then
- call writeln(STDERR, '+++ Error' fc 'in line' CallLine':' errortext(fc))
- else
- mess='+++ Error' fc 'in line' CallLine':' errortext(fc)
- 'Message' mess
- parse source Func .
- if Func = 'FUNCTION' then do
- 'DEFPUBSCREEN("Workbench")'
- exit "Err"
- end
- else do
- 'DEFPUBSCREEN("Workbench")'
- exit 10
- end
-
- calcp: Procedure
- arg g
- factk=1
- pp=0
- itts=0
- term=1
- k=0
- do while abs(term)>(exp(-23))
- term=.3989422804*((-1)**k)*(g**k)/(2*k+1)/(2**k)*(g**(k+1))/factk
- pp=pp+term
- k=k+1
- factk=factk*k
- end
- pp=pp+.5
- if (pp<.0000000001) then pp=0
- return pp
-
- calcpu: Procedure
-
- parse arg m,n,u
- work.=0
- fy.=0
- sum=0
- minmn=m
- maxmn=n
- mn1=m*n+1
- na=maxmn+1
- DO i=1 to na
- fy.i=1
- end
- work.1=0
- in=maxmn
- DO i=2 to minmn
- work.i=0
- in=in+maxmn
- na=in+2
- L=1+in/2
- k=i
- DO j=1 to L
- k=k+1
- na=na-1
- sum=fy.j + work.j
- fy.j=sum
- work.k=sum-(fy.na)
- fy.na=sum
- end
- end
- sum=0
- DO i=1 to mn1
- sum=sum+fy.i
- fy.i=sum
- end
- bb=u+1
- DO i=1 to bb
- fy.i=(fy.i)/sum
- if i=bb then PX=fy.i
- end
- return PX
-
- NPROB: Procedure Expose P Q PDF
-
- arg Z
- A0=0.5
- A1=0.398942280444
- A2=0.399903438504
- A3=5.75885480458
- A4=29.8213557808
- A5=2.62433121679
- A6=48.6959930692
- A7=5.92885724438
- B0=0.398942280385
- B1=3.8052E-8
- B2=1.00000615302
- B3=3.98064794E-4
- B4=1.98615381364
- B5=0.151679116635
- B6=5.29330324926
- B7=4.8385912808
- B8=15.1508972451
- B9=0.742380924027
- B10=30.789933034
- B11=3.99019417011
- ZABS = ABS(Z)
- Y = A0*Z*Z
- PDF = EXP(-Y)*B0
- SELECT
- WHEN (Z>=-1.28) & (Z<=1.28) then DO /*Z BETWEEN -1.28 AND +1.28*/
- Q = A0-ZABS*(A1-A2*Y/(Y+A3-A4/(Y+A5+A6/(Y+A7))))
- IF (Z<0) then do
- P = Q
- Q = 1.0-P
- End
- Else P = 1.0-Q
- RETURN
- End
- WHEN (Z>1.28) & (Z<=12.7) then do /*ZABS BETWEEN 1.28 AND 12.7 */
- Q = PDF/(ZABS-B1+B2/(ZABS+B3+B4/(ZABS-B5+B6/(ZABS+B7-B8/(ZABS+B9+B10/(ZABS+B11))))))
- IF(Z<0) then Do
- P = Q
- Q = 1.0-P
- End
- Else P = 1.0-Q
- RETURN
- End
- WHEN (Z<-1.28) & (Z>=-12.7) then do /*ZABS BETWEEN 1.28 AND 12.7 */
- Q = PDF/(ZABS-B1+B2/(ZABS+B3+B4/(ZABS-B5+B6/(ZABS+B7-B8/(ZABS+B9+B10/(ZABS+B11))))))
- IF(Z<0) then Do
- P = Q
- Q = 1.0-P
- End
- Else P = 1.0-Q
- RETURN
- End
- OTHERWISE /*Z FAR OUT IN TAIL*/
- Q = 0
- PDF = 0
- IF(Z<0) then do
- P = Q
- Q = 1.0-P
- End
- Else P = 1.0
- RETURN
- End
- Return